const char *help = "\
progname: .cc\n\
code2html: Ce programme affiche le profil d'intensité d'une image.\n\
version: Torch3 vision2.0, 2003-2005\n\
(c) Ewelle Richard (eerichard@ifi.edu.vn)\n";

#include "ImageRgb.h"
#include "Line2D.h"	
#include "Rectangle2D.h"
#include "tiffDiskXFile.h"
#include "xtprobeImageDiskXFile.h"
#include "CmdLine.h"

using namespace Torch;

//************** Déclarations des structures et variables **************//

	char *image_filename;
	bool verbose;
	int l,c,d,dir;
	const int taille=10000; 
 	ImageDiskXFile *image_file = NULL;
	Image *source = NULL;
	Image *image1 = NULL;
	Image *image2 = NULL;
	int rouge[taille];
	int vert[taille];
	int bleu[taille];   
	int gris[taille];     
	Point2D pta(0 ,0);
	Point2D ptb(0 ,0);


//************** Initialisation :  traitement de la commande et de l'image source **************//

int init(int argc, char **argv)
{

	// Construction de la ligne de commande
  	CmdLine cmd;
	cmd.setBOption("write log", false);
	
  	// Construction de l'option d'aide
  	cmd.info(help);

  	cmd.addText("\nArguments:");
  	cmd.addSCmdArg("image filename", &image_filename, "image filename");
  	cmd.addText("\nOptions:");
	cmd.addICmdOption("-l", &l, 100, "Le numero de la ligne étudiée");
	cmd.addICmdOption("-d", &dir, 0, "La direction de la ligne Verticale ou Horizontale");
	cmd.addICmdOption("-c", &c, 0, "La couleur de base de l'intensité");

	cmd.read(argc, argv);

  	// Création et chargement de l'image

	source = new ImageRgb();	
	image_file = new xtprobeImageDiskXFile(image_filename, "r");
	source->loadImageXFile(image_file);
	delete image_file;
	
	return source->height;

}

//******   Construction de la première image: tracé de la ligne sur l'image *******//

void constructimage1()
{

	image1 = new ImageRgb();	
	image1->copyFrom(source);
	
        if(dir==0)        // Tracer une ligne horizontale
        {
        int abs=l;

	Point2D A(0 ,abs);
	Point2D B(image1->width,abs);
	
	Line2D line(A, B);
	line.draw(image1, blue);
        }
        else
        {
         if(dir==1)     // Tracer une ligne verticale
          {
            int ord=l;

	    Point2D A(ord,0);
	    Point2D B(ord,image1->height);
	
	    Line2D line(A, B);
	    line.draw(image1, blue);
           
          }
        }

}

//******   Dessin du profil d'une couleur *******//

void drawprofil(int Val[taille],int c)
{
 int len;
    if(dir==0)
    {
     len = source->width;
    }else
    {
     len = source->height;
    }	
       
// Tracé de la courble

 for(int i=0;i< len;i++)
        {
        int j=i+1;

	pta.reset(i+10,Val[i]+10);
	ptb.reset(j+10,Val[j]+10);
        Line2D redline(pta, ptb);

 switch (c) 
   {
     case 1: redline.draw(image2, red);
             break;
     case 2: redline.draw(image2, green);
             break;
     case 3: redline.draw(image2, blue);
             break;
     case 4: redline.draw(image2, black);
             break;
     default: redline.draw(image2, black);
             break;

   }
       
 }    
}


//******   Construction de la deuxième image: le profil d'intensité *******//

void constructimage2()
{
       
   int max=(source->width)*(source->height)*3;
 
    if(dir==0)
    {
     image2 = new ImageRgb(source->width+20, 275);
    }else
    {
     image2 = new ImageRgb(source->height+20, 275);
    }	
       

// Colorier le fond de l'image en blanc.


	for(int x=0;x< source->width+20;x++)
        {
         for(int y=0;y< 275;y++)        
          image2->drawpixel(x,y,white);             
	
	} 

//Tracé du cadre rectangulaire qui délimite l'image. 

	Point2D A(10,10);
	Point2D B(image2->width-10,10);
	Point2D C(image2->width-10,image2->height-10);
	Point2D D(10,image2->height-10);

	Rectangle2D r1(A, B, C, D);
	r1.draw(image2, black);


// Extraction des composantes de chaque pixel de l'image

	int Tab[max];

        for(int i=0;i< max;i++)
        {
         Tab[i]=int(source->data[i]);             
	}      
	
        if(dir==0)  // Extraction de la ligne horizontale de position abs=l
        {
	int abs=l;
        for(int i=0;i< source->width;i++)
        {
        int aux = (3*(source->width*abs)+(3*i));

	rouge[i]=255-Tab[aux];
	vert[i]=255-Tab[aux+1];
	bleu[i]=255-Tab[aux+2];	
	gris[i]=int((rouge[i]+vert[i]+bleu[i])/3);	
 	
	}
        }else
         {
          if(dir==1)  // Extraction de la ligne verticale de position ord=l
          {
	   int ord=l;
           for(int i=0;i< source->height;i++)
           {
           int aux = 3*ord +3*source->width*i;

	   rouge[i]=255-Tab[aux];
	   vert[i]=255-Tab[aux+1];
	   bleu[i]=255-Tab[aux+2];	
	   gris[i]=int((rouge[i]+vert[i]+bleu[i])/3);	

          }

         }

    }      

// Dessin des profiles sur l'image crée.

 switch (c) 
   {
     case 1: drawprofil(rouge,c);
             break;
     case 2: drawprofil(vert,c);
             break;
     case 3: drawprofil(bleu,c);
             break;
     case 4: drawprofil(gris,c);
             break;
    default: drawprofil(rouge,c);
	     drawprofil(vert,c);
	     drawprofil(bleu,c);
             break;

   }
         	
}

//******   Sauvegarde des images *******//

void sauvegarde()
{

	image_file = new tiffDiskXFile("Ligne.tiff", "w");	
	image_file->writeHeader(image1->width, image1->height);
	image_file->writePixmap(image1->pixmap);
	delete image_file; 

	image_file = new tiffDiskXFile("Profils.tiff", "w");	
	image_file->writeHeader(image2->width, image2->height);
	image_file->writePixmap(image2->pixmap);
	delete image_file; 


}
//**************PROGRAMME PRINICIPAL **********************//

int main(int argc, char **argv)
{
        int hauteur;
 	hauteur=init(argc,argv); 
	if((l> hauteur)||(l< 0))
	{
		print("La ligne choisie doit être comprise entre 0 et la hauteur de l'image: < 0 - %d > \n",hauteur);
		
	}
        else
        {

// Construction des images
	
	constructimage1();  
	constructimage2();
	sauvegarde();

	}
	delete source;
	delete image1;
	delete image2;
       
	return(0);
}
